﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Selenium;
using Vowei.Core.Models;
using Vowei.Data;
using System.Data.Entity;
using System.Threading;

using TechTalk.SpecFlow;
using System.Diagnostics;

namespace vowei.specs
{
    public class SpecTestBase
    {
        static SpecTestBase()
        {
            Database.SetInitializer(new VoweiContextTestInitializer());
        }

        public class Constants
        {
            public const string TimeNeededToWaitForPageToLoad = "30000";

            public const int TimeNeededToWaitForAjaxToLoad = 5000;
            
            public const string DefaultTestProjectTitle = "Default Test Project";
        }

        protected static ISelenium Selenium { get; private set; }

        protected IVoweiContext ProductContext { get; private set; }

        protected Project DefaultTestProject { get; private set; }
                
        private void ConnectToProductDatabase()
        {
            var impl = new VoweiContextImpl(@"Data Source=.;Integrated Security=SSPI;Database=TaskConnect");
            ProductContext = new VoweiContext(impl);

            if (!ProductContext.Projects.Query.Any(p => p.Title == Constants.DefaultTestProjectTitle))
            {
                DefaultTestProject = new Project()
                {
                    Title = Constants.DefaultTestProjectTitle,
                    Owner = @"vowei\administrator"
                };
                ProductContext.Projects.Add(DefaultTestProject);
                ProductContext.SaveChanges();
            }
            else
            {
                DefaultTestProject = ProductContext.Projects.Query.Single(p => p.Title == Constants.DefaultTestProjectTitle);
            }
        }

        private void BeginTest()
        {
            Selenium = new DefaultSelenium("localhost", 4444, "*googlechrome", "http://localhost/");
            Selenium.Start();
        }

        protected void BeforeTestRun()
        {
            ConnectToProductDatabase();
            BeginTest();
        }

        protected void WaitPageToLoad()
        {
            Selenium.WaitForPageToLoad(Constants.TimeNeededToWaitForPageToLoad);
        }

        protected void WaitAjaxToFinish()
        {
            Thread.Sleep(Constants.TimeNeededToWaitForAjaxToLoad);
        }

        protected void RandomThinkTime()
        {
            var random = new Random();
            var sleepTime = random.Next(5) * 500;
            Thread.Sleep(sleepTime);
        }

        protected Project CreateProjectFromContext()
        {
            var project = new Project()
            {
                Owner = "active@vowei.com",
                StartDate = DateTime.Now,
                DueDate = DateTime.Now + TimeSpan.FromDays(30)
            };
            project.Title = project.ID.ToString();
            Trace.WriteLine(string.Format("[CreateProjectFromContext] - Create project: {0}", project.ID));

            ProductContext.Projects.Add(project);
            ProductContext.SaveChanges();

            return project;
        }

        protected Task CreateTaskHelper(Milestone milestone)
        {
            var task = new Task()
            {
                AssignedTo = "active@vowei.com",
                StartDate = DateTime.Now,
                DueDate = DateTime.Now + TimeSpan.FromDays(30),
                BelongsToMilestone = milestone,
                BelongsToMilestoneId = milestone.ID
            };
            task.Title = task.ID.ToString();

            return task;
        }

        protected Task CreateTaskFromContext(Milestone milestone)
        {
            var task = CreateTaskHelper(milestone);
            Trace.WriteLine(string.Format("[CreateTaskFromContext] - Create task: {0} in milestone: {1}", task.ID, milestone.ID));
            ProductContext.Tasks.Add(task);
            ProductContext.SaveChanges();

            return task;
        }

        protected Requirement CreateRequirementHelper(Milestone milestone)
        {
            var requirement = new Requirement()
            {
                AssignedTo = "active@vowei.com",
                BelongsToMilestone = milestone,
                BelongsToMilestoneId = milestone.ID
            };
            requirement.Title = requirement.ID.ToString();

            return requirement;
        }

        protected Requirement CreateRequirementFromContext(Milestone milestone)
        {
            var requirement = CreateRequirementHelper(milestone);
            Trace.WriteLine(string.Format("[CreateRequirementFromContext] - Create requirement: {0} in milestone: {1}", requirement.ID, milestone.ID));
            ProductContext.Requirements.Add(requirement);
            ProductContext.SaveChanges();

            return requirement;
        }

        protected Project FindProjectByTitle(string title)
        {
            return (Project)ProductContext.Projects.Query.Single(p => p.Title == title);
        }

        protected Requirement FindRequirementByTitle(string title)
        {
            return (Requirement)ProductContext.Requirements.Query.Single(r => r.Title == title);
        }

        protected Task FindTaskByTitle(string title)
        {
            return (Task)ProductContext.Tasks.Query.Single(t => t.Title == title);
        }
    }
}
